﻿using MainFrameDesign.Action;
using MainFrameDesign.Draws;
using MainInterface;
using MainProGrid;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MainFrameDesign.ContentContorl
{
    public class Div : IProperType,IBuilder
   {
       public CustomSelectObject PMC = new CustomSelectObject();
       public Div() 
       {
           padding = new Padding();
           padding.All = 10;
           padding.Top = 30;
           margin = new Padding();
           margin.All = 10;
           Height=30;
           CustomProperty pro = new CustomProperty(this, typeof(string), "名称", "Name", "设计", "组件的唯一名称",true);
           PMC.Properties.Add(pro);
           pro = new CustomProperty(this, typeof(Padding), "外边距", "Margin", "外观", "外边距");
           PMC.Properties.Add(pro);
           pro = new CustomProperty(this, typeof(Padding), "内边距", "Padding", "外观", "内边距");
           PMC.Properties.Add(pro);
       }
       private Padding padding ;
       public Padding Padding
       {
           get { return padding; }
           set { padding = value; }
       }
       private Padding margin;
       public Padding Margin
       {
           get { return margin; }
           set { margin = value; }
       }
       [Browsable(false)]
       public virtual int Width { get; set; }
       [Browsable(false)]
       public virtual int Height {get;set;}
       [Browsable(false)]
       public int DrawWidth { get; set; }
       public Rectangle Rect = new Rectangle();
       public Rectangle DrawRect = new Rectangle();
       public Rectangle ContentRect = new Rectangle();
       public Rectangle TopRect = new Rectangle();
       public Rectangle BottomRect = new Rectangle();
       public Rectangle TextRect = new Rectangle(0,0,70,25);
       public List<Div> Childs = new List<Div>();
       [Browsable(false)]
       public virtual Dom Root { get; set; }
       [Browsable(false)]
       public Div Parent { get; set; }
       public bool IsVitrul = false;
       public Point Location = new Point();
       public virtual string Name {get;set; }
       public bool IsSelected = false;
       public virtual Div AppendChild(Div div,bool isCallDraw) 
       {
           if (div == this) 
           {
               throw new Exception("自己不能添加自己");
           }
           div.Root = Root;
           div.Parent = this;
           this.Childs.Add(div);
           if (isCallDraw)
           {
               div.Root.CallDrawPar();
           }
           return div;
       }

       public virtual Div Before(Div div, bool isCallDraw) 
       {
           if (this.Parent == null || this.Root == null)
           {
               throw new Exception("根元素或父节点为空");
           }
           div.Root = Root;
           div.Parent = this.Parent;
           int index = this.Parent.Childs.IndexOf(this);
           this.Parent.Childs.Insert(index, div);
           if (isCallDraw)
           {
               div.Root.CallDrawPar();
           }
           return div;
       }

       public virtual Div After(Div div, bool isCallDraw) 
       {
           if (this.Parent == null || this.Root == null)
           {
               throw new Exception("根元素或父节点为空");
           }
           div.Root = Root;
           div.Parent = this.Parent;
           int index = this.Parent.Childs.IndexOf(this) + 1;
           this.Parent.Childs.Insert(index, div);
           if (isCallDraw)
           {
               div.Root.CallDrawPar();
           }
           return div;
       }

       public virtual Div Remove(Div div, bool isCallDraw) 
       {
           if (div.Parent != null) 
           {
               div.Parent.Childs.Remove(div);
           }
           div.Parent = null;
           if (isCallDraw&&div.Root!=null)
           {
               div.Root.CallDrawPar();
           }
           return div;
       }

       public virtual Div RemoveSelf(bool isCallDraw) 
       {
           return Remove(this, isCallDraw);
       }
       public virtual int CallHeight() 
       {
           this.Height=this.Margin.Top + this.Margin.Bottom + this.Padding.Top + this.Padding.Bottom;
           if (this.Childs.Count == 0)
           {
               this.Height += 30;
           }
           else 
           {
               foreach (var item in Childs)
               {
                   this.Height += item.CallHeight();
               }
           }
           return this.Height;
       }

       public virtual void CallWidth() 
       {
           this.Width = this.Parent.Width - this.Parent.Margin.Left - this.Parent.Padding.Left - this.Parent.Margin.Right - this.Parent.Padding.Right;
           foreach (var item in Childs)
           {
               item.CallWidth();
           }
       }

       public virtual void CallPoint() 
       {
           int x = Location.X+ Margin.Left + Padding.Left;
           int y = Location.Y + Margin.Top + Padding.Top;
           foreach (var item in Childs)
           {
               item.Location.X = x;
               item.Location.Y = y;
               item.CallPoint();
               y += item.Height;
           }
       }

       public virtual void CallRect() 
       {
           this.Rect.X = Location.X;
           this.Rect.Y = Location.Y;
           this.Rect.Width = this.Width;
           this.Rect.Height = this.Height;

           this.DrawRect.X = Location.X + Margin.Left;
           this.DrawRect.Y = Location.Y + Margin.Top;
           this.DrawRect.Width = this.Width - this.Margin.Left - this.Margin.Right;
           this.DrawRect.Height = this.Height - this.Margin.Top - this.Margin.Bottom;

           this.TextRect.X = this.DrawRect.X;
           this.TextRect.Y = this.DrawRect.Y;

           this.ContentRect.X = this.DrawRect.X + Padding.Left;
           this.ContentRect.Y = this.DrawRect.Y + Padding.Top;
           this.ContentRect.Width = this.DrawRect.Width - this.Padding.Left - this.Padding.Right;
           this.ContentRect.Height = this.DrawRect.Height - this.Padding.Top - this.Padding.Bottom;

          

           this.TopRect.X = this.DrawRect.X;
           this.TopRect.Y = this.Rect.Y;
           this.TopRect.Width = this.DrawRect.Width;
           this.TopRect.Height = this.Margin.Top;

           this.BottomRect.X = this.DrawRect.X;
           this.BottomRect.Y = this.Rect.Y + this.Rect.Height - Margin.Bottom;
           this.BottomRect.Width = this.DrawRect.Width;
           this.BottomRect.Height = this.Margin.Bottom;

           foreach (var item in Childs)
           {
               item.CallRect();
           }
       }

       public virtual Boolean IsInTop(Point P) 
       {
           if (this.TopRect.Contains(P)) 
           {
               return true;
           }
           return false;
       }

       public virtual Boolean IsInContent(Point P) 
       {
           if (this.ContentRect.Contains(P)) 
           {
               return true;
           }
           return false;
       }

       public virtual Boolean IsInBottom(Point P) 
       {
           if (this.BottomRect.Contains(P))
           {
               return true;
           }
           return false;
       }

       public virtual Div IsHover(Point P, ref AppendEnum appendenum) 
       {
             Div div=null;
             appendenum = AppendEnum.None;
             if (IsInTop(P)) 
             {
                 div = this;
                 appendenum = AppendEnum.Before;
             }
             else if (IsInContent(P)) 
             {
                 div = this;
                 appendenum = AppendEnum.Content;
                 foreach (var item in Childs)
                 {
                     div = item.IsHover(P, ref appendenum);
                     if (div != null) 
                     {
                         break;
                     }
                 }
             }
             else if (IsInBottom(P)) 
             {
                 div = this;
                 appendenum = AppendEnum.After;
             }
             return div;
       }

       public virtual Div IsSelect(Point P)
       {
           Div div = null;
           if (this.DrawRect.Contains(P)) 
           {
               foreach (var item in Childs)
               {
                   div = item.IsSelect(P);
                   if (div != null) 
                   {
                       break;
                   }
               }
               if (div == null) 
               {
                   div = this;
               }
           }
           return div;
       }

       public virtual void Draw(Graphics g) 
       {
           if (IsVitrul)
           {
               g.DrawRectangle(MyDraw.VituralPen, this.Rect);
           }
           else
           {
               DrawDrawRect(g);
               DrawContent(g);
               DrawTitle(g);
               if (this.Root != null && this.Root.IsDebug)
               {
                   DrawDebug(g);
               }
           }
           foreach (var item in Childs)
           {
               item.Draw(g);
           }
       }

       public virtual void DrawDebug(Graphics g)
       {
           g.FillRectangle(Brushes.Yellow, TopRect);
           g.FillRectangle(Brushes.Blue, BottomRect);
       }

       public virtual void DrawContent(Graphics g)
       {
           g.FillRectangle(Brushes.White, ContentRect);
           g.DrawRectangle(MyDraw.BorderPen, ContentRect);
       }

       public virtual void DrawTitle(Graphics g)
       {
           if (!string.IsNullOrEmpty(this.Name))
           {
               g.FillRectangle(Brushes.White, TextRect);
               g.DrawRectangle(MyDraw.BorderPen, TextRect);
               if (IsSelected)
               {
                   g.DrawString(this.Name, MyDraw.StringBoldFont, Brushes.Red, TextRect, MyDraw.TextAlign);
               }
               else
               {
                   g.DrawString(this.Name, MyDraw.StringBoldFont, MyDraw.StringBrush, TextRect, MyDraw.TextAlign);
               }

           }
       }

       public virtual void DrawDrawRect(Graphics g)
       {
           g.FillRectangle(MyDraw.PathBrush, DrawRect);
           g.DrawRectangle(MyDraw.BorderPen, DrawRect);
       }

       public virtual object GetValue(string name)
       {
           if (name == "Name") 
           {
               return this.Name;
           }
           if (name == "Margin") 
           {
               return this.Margin;
           }
           if (name == "Padding") 
           {
               return this.Padding;
           }
           return null;
       }

       public virtual Boolean SetValue(string name, object value)
       {
           if (name == "Name") 
           {
               this.Name = (string)value;
               return true;
           }
           else  if (name == "Margin") 
           {
               this.Margin=(Padding)value;
               return true;
           }
           else if (name == "Padding")
           {
               this.Padding = (Padding)value;
               return true;
           }
           return false;
       }
       public virtual string GetDom(string dom) 
       {
           string tem = Environment.NewLine+ "<div id='"+this.Name+"'>";
           tem += dom;
           foreach (var item in Childs)
           {
               tem += item.GetDom(string.Empty);
           }
           tem += Environment.NewLine + "</div>";
           return tem;
       }
       public virtual string GetCSS(string style) 
       {
           string tem = Environment.NewLine+"#"+this.Name+"{";
           tem += this.GetThisMargin();
           tem += this.GetThisPadding();
           tem += style;
           tem += "}";
           foreach (var item in Childs)
           {
               tem += item.GetCSS(string.Empty);
           }
           return tem;
       }
       public virtual string GetScript(string script) 
       {
           string tem = string.Empty;
           foreach (var item in Childs)
           {
               tem += item.GetScript(string.Empty);
           }
           return tem;
       }


       public  string GetThisMargin() 
       {
           return "Margin:" + Margin.Top + "px " + Margin.Right + "px " + Margin.Bottom + "px " + Margin.Left + "px;";
       }

       public  string GetThisPadding() 
       {
           return "Padding:" + Padding.Top + "px " + Padding.Right + "px " + Padding.Bottom + "px " + Padding.Left + "px;";
       }


       public virtual string GetReferences(string reference)
       {
           string tem = string.Empty;
           foreach (var item in Childs)
           {
               tem += item.GetReferences(string.Empty);
           }
           return tem;
       }


       public virtual string GetLinks(string links)
       {
           string tem = string.Empty;
           foreach (var item in Childs)
           {
               tem += item.GetLinks(string.Empty);
           }
           return tem;
       }


       public virtual void GetFiles(List<string> list)
       {
           foreach (var item in Childs)
           {
               item.GetFiles(list);
           }
       }
   }
}
